<?php

// +----------------------------------------------------------------------
// | 工作流数据表
// +----------------------------------------------------------------------

namespace common\model;

use think\model\RelationModel;

class StepWorkflowModel extends RelationModel
{

    // 工序流是否启用
    const OPEN_STEP_WORK_FLOW = 'yes';

    //自动验证
    protected $_validate = [
        ['name', '', '', self::MUST_VALIDATE, 'require', self::MODEL_INSERT],//必须字段
        ['project_template_id', '', '', self::MUST_VALIDATE, 'require', self::MODEL_INSERT],//必须字段
        ['name', '1,128', '', self::EXISTS_VALIDATE, 'length'],
        ['name,project_template_id', '', '', self::EXISTS_VALIDATE, 'unique'],
        ['code', '1,128', '', self::EXISTS_VALIDATE, 'length'],
        ['project_id,code,project_template_id,is_enable,name', '', '', self::EXISTS_VALIDATE, 'unique'],
        ['code', '', '', self::EXISTS_VALIDATE, 'alphaDash'],
        ['config', '', '', self::EXISTS_VALIDATE, 'array'],
        ['step_workflow_config', '', '', self::EXISTS_VALIDATE, 'array']

    ];

    //自动完成
    protected $_auto = [
        ['code', 'auto_fill_code', self::MODEL_INSERT, 'function_with_data'],
        ['config', 'json_encode', self::EXISTS_VALIDATE, 'function'],
        ['step_workflow_config', 'json_encode', self::EXISTS_VALIDATE, 'function'],
        ['uuid', 'create_uuid', self::MODEL_INSERT, 'function']
    ];

    // 自动完成后验证
//    protected $_validate_after_auto = [
//        ['project_id,code,project_template_id,is_enable,name', '', '', self::MUST_VALIDATE, 'unique', ''],
//    ];


    /**
     * 获取器：StepWorkflowConfig
     * @param $value
     * @param $data
     * @return mixed|string
     */
    public function getStepWorkflowConfigAttr($value, $data)
    {
        if (empty($value)) {
            return "";
        }
        $stepWorkflowConfigList = json_decode($value, true);
        // 查询上游工序id
        $upstreamStepId = [];
        foreach ($stepWorkflowConfigList['nodes'] ?? [] as $nodes) {
            foreach ($nodes as $nodeItem) {
                if (empty($nodeItem['step_id'])) {
                    continue;
                }
                $upstreamStepId[] = $nodeItem['step_id'];
            }
        }
        $stepUpstreamMap = [];
        if (!empty($upstreamStepId)) {
            $stepUpstreamList = model(StepUpstreamModel::class)
                ->where(['step_id' => ['IN', $upstreamStepId]])
                ->field('step_id,upstream_step_id,type,project_template_id,project_id')
                ->select();
            foreach ($stepUpstreamList as $stepUpstreamItem) {
                $stepUpstreamMapKey = sprintf('#step_id#%d#project_template_id#%d#project_id#%d', $stepUpstreamItem['step_id'] ?? 0, $stepUpstreamItem['project_template_id'] ?? 0, $stepUpstreamItem['project_id'] ?? 0);
                $stepUpstreamMap[$stepUpstreamMapKey][] = $stepUpstreamItem;
            }
        }
        $projectId = $data['project_id'] ?? 0;
        $projectTemplateId = $data['project_template_id'] ?? 0;
        $stepWorkflowConfigList['nodes'] = array_map(function ($nodes) use ($stepUpstreamMap, $projectTemplateId, $projectId) {
            $nodesList = [];
            foreach ($nodes ?? [] as $node) {
                $newUpstreamTask = [];
                $stepUpstreamMapKey = sprintf('#step_id#%d#project_template_id#%d#project_id#%d', $node['step_id'] ?? 0, $projectTemplateId, $projectId);
                foreach ($stepUpstreamMap[$stepUpstreamMapKey] ?? [] as $upstreamItem) {
                    $newUpstreamTask[] = [
                        'source_id' => $upstreamItem['step_id'] ?? '',
                        'target_id' => $upstreamItem['upstream_step_id'] ?? '',
                        'task_type' => $upstreamItem['type'] ?? '',
                    ];
                }
                $node['upstream_task'] = $newUpstreamTask;
                unset($newUpstreamTask);
                $nodesList[] = $node;
            }
            return $nodesList;
        }, $stepWorkflowConfigList['nodes'] ?? []);
        return $stepWorkflowConfigList;
    }

    /**
     * 获取器：Config
     * @param $value
     * @param $data
     * @return mixed|string
     */
    public function getConfigAttr($value, $data)
    {
        if (!empty($value)) {
            return json_decode($value, true);
        }
        return "";
    }
}
